package com.dyh.quickdemo.IdLock;

import com.dyh.quickdemo.demos.UnsafeFunc.UnsafeHelper;
import sun.misc.Unsafe;

/*
@Author=Joey Wheeler
@Date=2021/5/20 13:38

每个锁一个地方
[1,1,1,1]
synchronized
com.leqee.oms.wms.client.biz.scheduler.WmsOrderBackMessageBiz#saveOrderBackMessage
*/
public class IdLock {
    private volatile int state;
    private static final long stateOffset;
    private static final Unsafe unsafe = UnsafeHelper.getUnsafe();
    /*collide*/

    private  transient volatile Thread[] exclusiveOwnerThreads = new Thread[32];
//    private  transient volatile List<Thread> [] waitThreadss = new ArrayList[32];

    static {
        try {
            stateOffset = unsafe.objectFieldOffset
                    (IdLock.class.getDeclaredField("state"));
            /*
            * copy 导致的 bug  AbstractQueuedSynchronizer.class.getDeclaredField("state")
            * */

        } catch (Exception ex) { throw new Error(ex); }
    }

    /*
    偶数(8 &1) == 0
    */

    public final boolean tryLock(int idx){
        final Thread current = Thread.currentThread();
        if (idx<0||idx>31)
            throw new IllegalArgumentException("idx illegal");
        int s = state;
        /*敵*/
        Thread teki = exclusiveOwnerThreads[idx-1];
        if (teki!=null&& !teki.equals(current))
            return false;//被其它线程持有
        int oldVal = s & (1<<idx-1);
        if (oldVal==0){
            //看到目前是无锁状态
            s|=  1 <<(idx-1);
            if (!casState(state,s))
                return false;//被别的抢到了
            else{
                exclusiveOwnerThreads[idx-1] = current;
                return true;
            }

        }
       /*todo*/
        System.out.println(state);
        return false;
    }

    /*why use !=*/
    protected final boolean tryUnlock(int idx) {
        final Thread current = Thread.currentThread();
        Thread teki = exclusiveOwnerThreads[idx-1];
        if (!current.equals(teki))
            throw new IllegalMonitorStateException();
//        int s = state;
//        s ^=  1 <<(idx-1);
//        state = s;
        state ^= 1 <<(idx-1);
        exclusiveOwnerThreads[idx-1] = null;
        return true;
    }

    private  boolean casState(int expect, int update) {
        // See below for intrinsics setup to support this
        return unsafe.compareAndSwapInt(this, stateOffset, expect, update);
    }


}

